package com.h3c.ptability.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.eos.common.constant.StatusCodeEnum;
import com.eos.common.util.Result;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.h3c.ptability.cache.UserCache;
import com.h3c.ptability.client.DataCenterFeignClient;
import com.h3c.ptability.dto.LoginUserDTO;
import com.h3c.ptability.entity.PtApp;
import com.h3c.ptability.entity.PtUploadFile;
import com.h3c.ptability.entity.SdOperLog;
import com.h3c.ptability.enums.FileOpTypeEnum;
import com.h3c.ptability.service.CommService;
import com.h3c.ptability.utils.AppBusinessException;
import com.h3c.ptability.utils.CommonUtil;
import com.h3c.ptability.utils.ReturnCodeData;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.Data;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.Base64Utils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.*;

@Api(tags = " Common公共接口")
@CrossOrigin
@RestController
@RequestMapping(value = "/comm", produces = "application/json;charset=utf-8")
public class CommController {

    @Autowired
    CommService commService;
    @Value("${system.runMode}")
    private String runMode;
    @Resource
    private DataCenterFeignClient dataCenterFeignClient;

    @RequestMapping("/clearCacheData")
    @ResponseBody
    public Result clearCacheData(HttpServletRequest request) {
        String realIP = CommonUtil.getIp(request);
        String remoteAddr = realIP + ":" + request.getRemotePort();
        commService.saveLoginHistory(UserCache.getLoginUserId(), commService.getLoginUserNameWithNoException(), "退出系统", remoteAddr);
        commService.clearCacheData();
        return new Result(true, 20000, "退出系统缓存清理成功", new SdOperLog());
    }

//    @RequestMapping("/switchUser")
//    @ResponseBody
//    public Result switchUser(@RequestBody SdUser user) {
//        commService.switchUser(user);
//        return new Result(true, 20000, "临时用户转换成功", new SdOperLog());
//    }

//    @RequestMapping("/checkNewWorker")
//    @ResponseBody
//    public Result checkNewWorker(@RequestBody SdUser user) {
//        String value=commService.checkNewWorker();
//        return new Result(true, 20000, "新员工",value);
//    }

    @ApiOperation(value = "查询Redis当前缓存值", notes = "按权限查询菜单")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "key", value = "redis key", required = true, dataType = "String", paramType = "query")
    })
    @RequestMapping("/getReidsValue")
    @ResponseBody
    public Result getReidsValue(@RequestParam("key") String key) {
        String value = commService.getReidsValue(key);
        return new Result(true, 20000, "查询成功", value);
    }

    /**
     * 登录时，获取域名加密值
     * @return
     */
    @ApiOperation(value = "对当前系统地址加密，传给sso页面；sso解密url，sso登录后回跳到我们系统；", notes = "登录时，获取域名加密值")
    @RequestMapping(value = "/encodeUrl", method = RequestMethod.POST)
    @ResponseBody
    public Result encodeUrl(@RequestBody LoginUserDTO loginUser) throws Exception {
         return new Result(true, StatusCodeEnum.LOGIN_SUCCESS, commService.loginUrl(loginUser.getLocalUrl()));
    }

    /**
     * 重新加载缓存数据
     * @return
     */
    @ApiOperation(value = "重新加载缓存数据")
    @RequestMapping(value = "/initCacheData", method = RequestMethod.POST)
    @ResponseBody
    public Result initCacheData() throws Exception {
        commService.initData();
        return new Result(true, StatusCodeEnum.NORMAL);
    }

//    /**
//     * 登录时，获取验证码
//     * @return
//     */
//    @ApiOperation(value = "sso登录成功后，前端将ticket传给后端，验证身份，并获取验证码", notes = "登录时，获取域名加密值")
//    @RequestMapping(value = "/getMobileValidCode", method = RequestMethod.POST)
//    @ResponseBody
//    public Result getMobileValidCode(@RequestBody LoginUserDTO loginUser, HttpServletRequest request) throws Exception {
//        String ticket = loginUser.getTicket();
//        if (!StringUtils.isEmpty(ticket)) {
//            LoginUserDTO loginUserDTO = commService.getMobileValidCode(ticket);
//            return new Result(true, StatusCodeEnum.NORMAL, loginUserDTO);
//        }else{
//            throw new AppBusinessException("sso-ticket不能为空");
//        }
//    }
//
//    /**
//     * 验证输入的手机验证码
//     * @return
//     */
//    @ApiOperation(value = "sso登录成功后，前端将ticket传给后端，验证身份，并获取验证码", notes = "登录时，获取域名加密值")
//    @RequestMapping(value = "/validateMobileCode", method = RequestMethod.POST)
//    @ResponseBody
//    public Result validateMobileCode(@RequestBody LoginUserDTO loginUser, HttpServletRequest request) throws Exception {
//        String domainAccount = loginUser.getAccount();
//        String inputMobileValidCode = loginUser.getMobileValidCode();
//
//        if(StringUtils.isEmpty(domainAccount) || StringUtils.isEmpty(inputMobileValidCode) ){
//            throw new AppBusinessException("域账号和手机验证码不能为空");
//        }
//        String generateMobileValidCode = commService.getReidsValue(BusiEnumDefine.REDIS_AUTH_CODE_PREFIX + domainAccount);
//        if(!StringUtils.isEmpty(generateMobileValidCode)
//                && generateMobileValidCode.equals(inputMobileValidCode)){
//            Map<String, Object> userLoginMap = commService.getToken(loginUser);
//            LoginUserDTO loginUserResult = (LoginUserDTO) userLoginMap.get("info");
//            String realIP = CommonUtil.getIp(request);
//            String remoteAddr = realIP + ":" + request.getRemotePort();
//            commService.saveLoginHistory(loginUserResult.getUserId(), loginUserResult.getUserName(), "登录系统", remoteAddr);
//            return new Result(true, StatusCodeEnum.LOGIN_SUCCESS, userLoginMap);
//        }else{
//            throw new AppBusinessException("手机验证码校验失败");
//        }
//    }


    /**
     * 登录
     *
     * @return
     */
    @ApiOperation(value = "登录获取token接口", notes = "登录获取token接口")
    @RequestMapping(value = "/token", method = RequestMethod.POST)
    @ResponseBody
    public Result getToken(@RequestBody LoginUserDTO loginUser, HttpServletRequest request) throws Exception {
        String ticket = loginUser.getTicket();
        if (!StringUtils.isEmpty(ticket)) {
            Map<String, Object> userLogin = commService.getToken(ticket);
            LoginUserDTO loginUser2 = (LoginUserDTO) userLogin.get("info");
            String realIP = CommonUtil.getIp(request);
            String remoteAddr = realIP + ":" + request.getRemotePort();
            commService.saveLoginHistory(loginUser2.getUserId(), loginUser2.getUserName(), "登录系统", remoteAddr);
            return new Result(true, StatusCodeEnum.LOGIN_SUCCESS, userLogin);
        } else {
            return new Result(true, StatusCodeEnum.LOGIN_SUCCESS, commService.loginUrl(loginUser.getLocalUrl()));
        }

    }

    @RequestMapping(value = "/getPtabilityToken", method = RequestMethod.POST)
    @ResponseBody
    public Result getPtabilityToken(@RequestBody LoginUserDTO loginUser, HttpServletRequest request) throws Exception {
        String ticket = loginUser.getTicket();
        if (!StringUtils.isEmpty(ticket)) {
            Map<String, Object> userLogin = commService.getTokenOnly(ticket);
            return new Result(true, StatusCodeEnum.LOGIN_SUCCESS, userLogin);
        } else {
            return new Result(true, StatusCodeEnum.LOGIN_SUCCESS, commService.loginUrl(loginUser.getLocalUrl()));
        }
    }

    @ApiOperation(value = "登录获取token接口", notes = "登录获取token接口")
    @RequestMapping(value = "/tokenTest", method = RequestMethod.POST)
    @ResponseBody
    public Result getTokenTest(@RequestBody LoginUserDTO loginUser) throws Exception {
        String account = loginUser.getAccount();
//        commService.checkRunModeIsProd();
        if (!StringUtils.isEmpty(account)) {
            Map<String, Object> token;
            if (loginUser.getIsReserveStaff() != null && loginUser.getIsReserveStaff()) {
                token = commService.getTokenOnlyByAccount(account, true);
            } else {
                token = commService.getTokenOnlyByAccount(account, false);
            }
            return new Result(true, StatusCodeEnum.LOGIN_SUCCESS, token);
        } else {
            return new Result(true, StatusCodeEnum.LOGIN_SUCCESS, commService.loginUrl(loginUser.getLocalUrl()));
        }

    }

    @ApiOperation(value = "企业微信登录获取token接口", notes = "企业微信登录获取token接口")
    @RequestMapping(value = "/wxToken", method = RequestMethod.GET)
    @ResponseBody
    public Result getWxToken(String ticket, String localUrl, String userId, HttpServletRequest request) throws Exception {
        if (!StringUtils.isEmpty(ticket)) {
            Map<String, Object> userLogin = commService.getWxToken(ticket, userId);
            LoginUserDTO loginUser = (LoginUserDTO) userLogin.get("info");
            String realIP = CommonUtil.getIp(request);
            String remoteAddr = realIP + ":" + request.getRemotePort();
            commService.saveLoginHistory(loginUser.getUserId(), loginUser.getUserName(), "登录系统", remoteAddr);
            return new Result(true, StatusCodeEnum.LOGIN_SUCCESS, userLogin);
        } else {
            return new Result(true, StatusCodeEnum.LOGIN_SUCCESS, commService.loginUrl(localUrl));
        }

    }

    @ApiOperation(value = "查询登录人信息接口", notes = "首页getMenu已经返回了这个结构")
    @RequestMapping("/queryLoginUserInfo")
    @ResponseBody
    public Result queryLoginUserInfo() {
        LoginUserDTO loginUserDTO = UserCache.queryLoginUserInfo();
        return new Result(true, 2000, "", loginUserDTO);
    }


    @PostMapping(value = "/downloadTest")
    @ResponseBody
    public Map<String, String> downloadTest() {
        try {
            File downLoadFile = commService.downloadTest();
            FileInputStream inputStream = new FileInputStream(downLoadFile);
            byte[] buffer = new byte[(int) downLoadFile.length()];
            inputStream.read(buffer);
            inputStream.close();
            Map<String, String> result = new HashMap<>();
            result.put("file", Base64Utils.encodeToString(buffer));
            result.put("filename", downLoadFile.getName());
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            throw new AppBusinessException("文件下载异常");
        }
    }

    @PostMapping(value = "/parseFile")
    @ResponseBody
    public String parseFile(@RequestParam("file") MultipartFile file,
                            @RequestParam("templateCode") String templateCode) {
        try {
            return commService.parseExcelByTemplate(templateCode, file);
        } catch (Exception e) {
            e.printStackTrace();
            throw new AppBusinessException("文件解析异常");
        }
    }

    //查询登陆人有权限的app
    @GetMapping(value = "/queryAppList")
    public ResponseEntity<JSONObject> queryAppList() {
        List<PtApp> appList=commService.queryAppForLoginUser();
        JSONObject data = new JSONObject();
        data.put("data", appList);
        data.put("msg", "20000");
        data.put("code", ReturnCodeData.SUCCESS);
        return new ResponseEntity<>(data, HttpStatus.ACCEPTED);
    }


    @PostMapping(value = "/previewUploadFile")
    @ResponseBody
    public Result previewUploadFile(@RequestParam("fileId") String fileId,
                                    @RequestParam("busiId") String busiId,
                                    @RequestParam("busiType") Integer busiType) {
        Map<String, String> previewFile = null;
        if (!StringUtils.isEmpty(fileId)) {
            previewFile = commService.previewFile(fileId);
        } else {
            previewFile = commService.previewFile(busiId, busiType);
        }
        return new Result(true, StatusCodeEnum.NORMAL, previewFile);
    }

    /**
     * 文件上傳返回上傳的文件id
     *
     * @return
     */
    @PostMapping("uploadFile")
    public Result uploadFile(@RequestParam("uploadFile") MultipartFile uploadFile,
                             @RequestParam("busiType") String busiType,
                             @RequestParam(value = "busiId",required = false)String busiId,
                             @RequestParam(value = "appId")String appId) {
        File file = null;
        try {
            file = new File("" + uploadFile.getOriginalFilename());
            FileUtils.copyInputStreamToFile(uploadFile.getInputStream(), file);
            PtUploadFile fileObj  = commService.uploadFileToSfs(busiType, file, busiId,appId,"-1");
            commService.recordFileOperationLog(uploadFile.getOriginalFilename(), uploadFile.getSize(), FileOpTypeEnum.IMPORT);
            file.delete();
            return new Result(true, StatusCodeEnum.NORMAL, fileObj);
        } catch (Exception e) {
            throw new AppBusinessException("上传文件失败");
        } finally {
            if (file != null) {
                file.delete();
            }
        }
    }

    @GetMapping("/deleteRedisKey")
    public Result deleteRedisKey(String key) {
        commService.deleteRedisKey(key);
        return new Result(true, StatusCodeEnum.NORMAL);
    }


    @GetMapping("/deleteSfsFile")
    public Result deleteSfsFile(String fileId) {
        commService.deleteSfsFile(fileId);
        return new Result(true, StatusCodeEnum.NORMAL);
    }

    @RequestMapping("/getPortrait/{workerId}")
    public void syncPortrait(@PathVariable("workerId") String workerId, HttpServletRequest request, HttpServletResponse response) throws Exception{


        LinkedHashMap portrait = commService.getPortrait(workerId);
        BufferedInputStream bis = new BufferedInputStream(new ByteArrayInputStream(Base64.getDecoder().decode(portrait.get("com_img").toString())));
        BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());
        response.setHeader("Content-Type", "image/jpeg");
        byte b[] = new byte[1024];
        int read;
        try {
            while ((read = bis.read(b)) != -1) {
                bos.write(b, 0, read);
            }
        } catch (Exception e) {
            // TODO: handle exception
        } finally {
            if (bos != null) {
                bos.close();
            }
            if (bis != null) {
                bis.close();
            }
        }
    }

    @Data
    static class PunishDTO {
        @JsonFormat(pattern = "yyyy-MM-dd")
        private Date startTime;
        @JsonFormat(pattern = "yyyy-MM-dd")
        private Date endTime;
    }

    @PostMapping("queryPunishment")
    public Result<JSONArray> queryPunishment(@RequestBody PunishDTO dto) {
        JSONObject s = dataCenterFeignClient.syncPunishRecord(JSONObject.toJSONStringWithDateFormat(dto, "yyyy-MM-dd"), commService.getAppToken());
        Integer code = s.getInteger("code");
        if (code == 20216) {
            return new Result<>(true, StatusCodeEnum.NORMAL, s.getJSONArray("data"));
        }
        return new Result<>(true, StatusCodeEnum.NORMAL, new JSONArray());
    }

}
